/*
 * weightedmajority.cpp
 *
 *  Created on: Feb 28, 2011
 *      Author: tqlong
 */

#include "perceptron.h"
#include <iostream>

void WeightedMajority::setParameters(const std::vector<double>& params)
{
  if (params.size() > 0) beta_ = params[0];
}

double WeightedMajority::update(const arma::vec& x, double y, double p)
{
  double error = 0.5 * (y - p);
  for (int i = 0; i < n_expert(); i++) {
    expert_[i]->update(x, y, pred_[i]);
    if (y * p < 0 && y * pred_[i] <= 0) {  // a mistake and a mistaken expert
      weight_[i] *= beta_;
    }
  }
  return error;
}

double WeightedMajority::predict(const arma::vec& x)
{
  double w_pos = 0, w_neg = 0;
  for (int i = 0; i < n_expert(); i++) {
    pred_[i] = expert_[i]->predict(x);
    if (pred_[i] > 0) w_pos += weight_[i];
    else w_neg += weight_[i];
  }
  predict_ = (w_pos > w_neg) ? 1 : -1;
  return predict_;
}

void WeightedMajority::print() const
{
  for (int i = 0; i < n_expert(); i++) {
    std::cout << "expert[" << i << "] = " << weight_[i] << "\n";
    expert_[i]->print();
    std::cout << "\n";
  }
}

void WeightedMajority::add(OnlineLearningAlgorithm& algo)
{
  expert_.push_back(&algo);
  pred_.push_back(0);
  weight_.push_back(1.0);
}
